package com.college.common.utils.security;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;


@Slf4j
public class AESSignatureUtil {

	private static final String encryptKey = "740b8ce727634739a77654f8dc4711a3";

	public static String decrypt(String content) {
		return decrypt(content, encryptKey);
	}

	/**
	 * 基于password生成密钥加密
	 *
	 * @param content  需要加密的内容
	 * @param password 加密密码，用于作为密钥的seed
	 * @return AES 加密后的2进制字节码
	 */
	public static String encrypt(String content, String password) {
		try {
			// 生成密钥
			KeyGenerator keyGen = KeyGenerator.getInstance("AES");
			SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
			secureRandom.setSeed(password.getBytes());
			keyGen.init(128, secureRandom);
			SecretKey secretKey = keyGen.generateKey();
			// 创建密码器
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);
			// 初始化
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);
			// 加密
			byte[] encryptByteData = cipher.doFinal(byteContent);

			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(encryptByteData);
		} catch (Exception e) {
			log.error("加密失败", e);
		}
		return null;
	}

	/**
	 * 解密
	 *
	 * @param contentString 已加密需解密的字符串
	 * @param password      解密秘钥
	 * @return
	 */
	public static String decrypt(String contentString, String password) {
		try {
			BASE64Decoder decoder = new BASE64Decoder();
			KeyGenerator kgen = KeyGenerator.getInstance("AES");
			SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
			random.setSeed(password.getBytes());
			kgen.init(128, random);
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(kgen.generateKey().getEncoded(), "AES"));
			byte[] decryptBytes = cipher.doFinal(decoder.decodeBuffer(contentString));
			return new String(decryptBytes);
		} catch (Exception e) {
			log.error("解密失败", e);
		}
		return null;
	}

	/**
	 * 签名
	 *
	 * @param contentString 签名所需的参数字符串
	 * @return
	 */
	public static String sign(String contentString) {
		contentString = contentString + encryptKey;
		String sign = DigestUtils.md5Hex(contentString);
		return sign;
	}

	/**
	 * 验签
	 *
	 * @param sign          签名串
	 * @param contentString 请求参数字符串
	 * @return
	 */
	public static boolean verify(String sign, String contentString) {
		String verifySign = sign(contentString);
		if (sign.equals(verifySign)) {
			return true;
		} else {
			return false;
		}
	}



	public static void main(String[] args) {
		System.out.println(encrypt("12345674567", "sonGzsx3DgID57CBzM3QHA=="));
		/*Map<String, String> params = new HashMap<>();
		params.put("user_name", "邓李平");
		params.put("mobile", "17815122787");
		params.put("credit_no", "513901199604222333");
		String sortedString = convertMap2String(params);
		System.out.println("排序后的请求参数为：" + sortedString);
		String encryptParam = encrypt(sortedString, encryptKey);
		System.out.println("加密数据为：" + encryptParam);
		JSONObject jsonObject1 = new JSONObject();
		jsonObject1.put("params", encryptParam);
		System.out.println("jsonObject1 = " + jsonObject1);
		Map<String, String> signMap = new HashMap<>();
		signMap.put("partner_id", "UK1539238914824812");
		signMap.put("params", encryptParam);
		System.out.println("signMap = " + JSON.toJSONString(signMap));
		String sign = sign(convertMap2String(signMap));
		System.out.println("签名为：" + sign);
		signMap.put("sign", sign);
		JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(signMap));
		sign = (String) jsonObject.remove("sign");
		Map<String, String> reusltMap = (Map<String, String>) JSON.parse(jsonObject.toJSONString());
		System.out.println("reusltMap = " + reusltMap);
		System.out.println("sign = " + sign);
		String contentString = convertMap2String(reusltMap);
		System.out.println("contentString = " + contentString);
		if (!verify(sign, contentString)) {
			LogPrintUtils.info(log, "签名失败");
			return;
		}
		String decryptParams = decrypt(signMap.get("params"), encryptKey);
		Map<String, String> paramMap = convertString2Map(decryptParams);
		System.out.println("解密后的数据为：" + JSONObject.toJSONString(paramMap));*/

	}
}
